import operator
import time
from osv import osv, fields
from osv.orm import intersect
import tools.sql
from tools import config
from tools.translate import _
import netsvc
import datetime

class res_currency(osv.osv):
    _inherit='res.currency'
    
    def round(self, cr, uid, currency, amount,context={}):
        if 'rounding' in context:
            #return amount
            if context['rounding']==0:
                return amount
            else:
                return round(amount /0.00000001) *0.00000001
        else:
            try:
                if currency.rounding == 0:
                    return 0.0
                else:
                    # /!\ First member below must be rounded to full unit!
                    # Do not pass a rounding digits value to round()
                    return round(amount / currency.rounding) * currency.rounding
            except:
                return 0.0

    def _current_rate(self, cr, uid, ids, name, arg, context={}):   
        res={}
        if 'date' in context:
            date=context['date']
        else:
            date=time.strftime('%Y-%m-%d')
        date= date or time.strftime('%Y-%m-%d')
        for id in ids:
            cr.execute("SELECT currency_id, rate FROM res_currency_rate WHERE currency_id = %s AND name <= '%s' ORDER BY name desc LIMIT 1" % (id, date))
            if cr.rowcount:
                id, rate=cr.fetchall()[0]
                res[id]=rate
            else:
                res[id]=0
        return res
    
    def current_rate_get(self, cr, uid):
        cr.execute("select id from res_currency where code='USD'")
        ids = map(lambda x:x[0], cr.fetchall())
        # Get ExRate Between VND and USD
        cr.execute("select trim(to_char(rate,'9,999,990.00')) as rate FROM res_currency_rate WHERE \
                    currency_id = (select id from res_currency where code='USD' limit 1)\
                     AND name = '%s' ORDER BY name desc LIMIT 1" % time.strftime('%Y-%m-%d'))
        if cr.rowcount:
            res=cr.fetchone()
            rate=res[0]
        else:
            rate='Not Avaiable'
        return (ids, rate)
    
    def _get_default_id(self,cr,uid,context={}):
        rate_one_ids=self.pool.get('res.currency.rate').search(cr,uid,[('rate','=',1.0)])
        default_curr_id=False
        if not rate_one_ids:
            raise osv.except_osv("Warning","Please check default currency !")
        else:
            default_curr_id=self.pool.get('res.currency.rate').read(cr,uid,rate_one_ids,['currency_id'])#[0]['currency_id'][0]
            if not default_curr_id and len(default_curr_id)<>1:
                raise osv.except_osv("Warning","Please check default currency !")
            else:
                default_curr_id=default_curr_id[0]['currency_id'][0]
        if context.get('curr_name',False):
            curr_name=self.read(cr,uid,[default_curr_id],['code'])[0]['code']
            default_curr_id=curr_name.upper().strip()
        return default_curr_id

    def _create_currency(self,cr,uid,currency_id=False,context=None):
        default_curr_id=self._get_default_id(cr,uid)
#        rate_one_ids=self.pool.get('res.currency.rate').search(cr,uid,[('rate','=',1.0)])
#        #raise osv.except_osv("Warning",rate_one_ids)
#        if len(rate_one_ids)>1 or not rate_one_ids:
#            raise osv.except_osv("Warning","Please check default currency !")
#        else:
#            try:            
#                default_curr_id=self.pool.get('res.currency.rate').read(cr,uid,rate_one_ids,['currency_id'])[0]['currency_id'][0]
#            except:
#                raise osv.except_osv("Warning","Please check default currency !")
#            #
        if not default_curr_id:
            return False
        elif 'project_id' in context:
            if context['project_id']:
                project_code=self.pool.get('account.analytic.account').read(cr,uid,[context['project_id']],['code'])[0]['code']
                if project_code:
                    context['project_code']=project_code
        if 'project_code' in context:
            other_currency_ids=self.search(cr,uid,[('id','<>',default_curr_id)])
            other_currency_codes=self.read(cr,uid,other_currency_ids,['code'])
            lists=[]
            result=currency_id
            for code in other_currency_codes:
                if len(code['code'].strip())==3:
                    lists.append(code['code'])
            for code in lists:
                project_curr_code=context['project_code'].upper().strip()+"-"+code.upper().strip()
                project_curr_id=self.search(cr,uid,[('code','ilike',project_curr_code)])                
                if project_curr_id:
                    result=project_curr_id[0]
                else:
                    curr_code=project_curr_code
                    current_rate_id=self.search(cr,uid,[('code','=',code)])
                    current_currency=self.read(cr,uid,current_rate_id,['rate','rounding','accuracy'])
                    current_rate=current_currency[0]['rate']
                    current_rounding=current_currency[0]['rounding']
                    current_acc=current_currency[0]['accuracy']                
                    project_curr_id=self.create(cr,uid,{'name':code,'code':curr_code,'rounding':current_rounding
                                                       ,'accuracy':current_acc,'current_amount':current_rate})
                    if current_rate_id[0]==result:
                        result=current_rate_id[0]                
        return result    
   
    def _suggest_code(self, cr, uid, context={}):
        suggest_code=''
        if 'project_curr' in context:
            try:
                suggest_code=context['project_curr'].upper().strip()+'-'
            except:
                suggest_code='PH'
        return suggest_code
    _columns={
              'code': fields.char('Code', size=30),
              'current_amount':fields.float('Amount',invisible=True),
              'rate': fields.function(_current_rate, method=True, string='Current Rate', digits=(12,6)),
              'rounding': fields.float('Rounding factor', digits=(12,6)),
              }
    _defaults = {
        'active': lambda *a: 1,
        'accuracy':lambda *a: 4,
        'rounding': lambda *a: 0.000001,
        #'code':_suggest_code,
    }
    
    def _onchage_name(self, cr, uid, ids,name=False,context=None):
        val={}
        code=context.get('project_curr',False)
        #if 'project_curr' in context: 
        #raise osv.except_osv("E",str(code))
        if name and code:
            val={'code':code.upper().strip()+'-'+name.upper().strip()}
        return {'value':val}
    
#    def fields_get(self, cr, uid, fields=None, context=None):
#        res = super(res_currency, self).fields_get(cr, uid, fields, context)        
#        if 'current_amount' in fields and context.get('project_curr',False):
#            res['current_amount']['invisible']=False
#            res['rate_ids']['invisible']=True
#            res['rate']['invisible']=True
#        return res
    
#    def write(self, cr, uid, ids, vals, context=None):
#        if 'current_amount' in vals:
#            if context.get('project_curr',False) and vals['current_amount']>0: #Update for Rate for job
#                #raise osv.except_osv("E",ids)
#                cr.execute("Update res_currency_rate set rate="+str(vals['current_amount']) +" where currency_id in (" + str(ids[0]) +")")                    
#        return super(res_currency, self).write(cr, uid, ids, vals, context=context)
    
#    def create(self, cr, uid, vals, context=None):
#        currency_id=super(res_currency, self).create(cr, uid, vals, context=context)
#        if 'current_amount' in vals:
#            curr_rate_obj=self.pool.get('res.currency.rate')
#            new_rate=curr_rate_obj.create(cr,uid,{'name':datetime.date(1990,1,1),'rate':vals['current_amount'],'currency_id':currency_id})
#        return currency_id   
    
    
    def compute(self, cr, uid, from_currency_id, to_currency_id, from_amount, round=True, context={}, account=None, account_invert=False):
        if not from_currency_id:
            from_currency_id = to_currency_id
        if not to_currency_id:
            to_currency_id = from_currency_id
        xc = self.browse(cr, uid, [from_currency_id,to_currency_id], context=context)
        from_currency = (xc[0].id == from_currency_id and xc[0]) or xc[1]
        to_currency = (xc[0].id == to_currency_id and xc[0]) or xc[1]
        if from_currency['rate'] == 0 or to_currency['rate'] == 0:
            date = context.get('date', time.strftime('%Y-%m-%d'))
            if from_currency['rate'] == 0:
                code = from_currency.code
            else:
                code = to_currency.code
            raise osv.except_osv(_('Error'), _('No rate found \n' \
                    'for the currency: %s \n' \
                    'at the date: %s') % (code, date))
        rate = from_currency.rate/to_currency.rate
        if account and (account.currency_mode=='average') and account.currency_id:
            q = self.pool.get('account.move.line')._query_get(cr, uid, context=context)
            cr.execute('select sum(debit-credit),sum(amount_currency) from account_move_line l ' \
              'where l.currency_id=%s and l.account_id=%s and '+q, (account.currency_id.id,account.id,))
            tot1,tot2 = cr.fetchone()
            if tot1 and not account_invert:
                rate = float(tot2)/float(tot1)
            elif tot2 and account_invert:
                rate = float(tot1)/float(tot2)
        if to_currency_id==from_currency_id:
            if round:
                return self.round(cr, uid, to_currency, from_amount)
            else:
                return from_amount
        else:
            if round:
                return self.round(cr, uid, to_currency, from_amount * rate)
            else:
                return (from_amount * rate)
res_currency()

class res_currency_rate(osv.osv):
    _name = "res.currency.rate"
    _description = "Currency Rate"
    _columns = {
        'name': fields.date('Date', required=True, select=True),
        #'rate_in_vnd':fields.float('Rate',required=True,digits=(12,2)),
        'rate': fields.float('Rate', digits=(12,6),help='The rate of the currency to the currency of rate 1'),
        'currency_id': fields.many2one('res.currency', 'Currency', readonly=True),
    }
    _defaults = {
        'name': lambda *a: time.strftime('%Y-%m-%d'),        
    }
    _order = "name desc"
    
#    def name_get(self, cr, uid, ids, context=None):
#        if not len(ids):
#            return []
#        reads = self.read(cr, uid, ids, ['rate'], context)
#        res = []
#        for record in reads:
#            name = record['rate']
#            res.append((record['id'], name))
#        return res
res_currency_rate()